


    /* a raphael pie chart */
    a_rjs_pie: function()
    {
      var self = this;

      self.requirePaper = true;

      self.init = function()
      {
      }

      self.setValue = function(values)
      {
         self.values = values;
      }

      self.render = function()
      {
        self.paper.clear();
        if (self.values.length==0)
        return;

          var cx = self.width/2;
          var cy = self.height/2;
          var r = Math.min(cx, cy)/2;
          var labels =['a','b','c'];
          var stroke ="#F7F5F1";

          var angle = 0,
            total = 0,
            start = .5,
            process = function (j) {
                var value = self.values[j],
                    angleplus = 360 * value / total,
                    popangle = angle + (angleplus / 2),
                    color = "hsb(.3, 1, " + start + ")",
                    ms = 500,
                    delta = 3,
                    p = self.sector(cx, cy, r, angle, angle + angleplus, {gradient: "90-" + color + "-" + color, stroke: stroke, "stroke-width": 2});
                    //txt = paper.text(cx + (r + delta + 55) * Math.cos(-popangle * rad), cy + (r + delta + 25) * Math.sin(-popangle * rad), labels[j]).attr({fill: bcolor, stroke: "none", opacity: 0, "font-family": 'Fontin-Sans, Arial', "font-size": "20px"});
                p.mouseover(function () {
                    p.animate({scale: [1.1, 1.1, cx, cy]}, ms, "elastic");
                    //txt.animate({opacity: 1}, ms, "elastic");
                }).mouseout(function () {
                    p.animate({scale: [1, 1, cx, cy]}, ms, "elastic");
                    //txt.animate({opacity: 0}, ms);
                });
                angle += angleplus;
                //chart.push(p);
                //chart.push(txt);
                start += .15;
            };
        for (var i = 0, ii = self.values.length; i < ii; i++)
            total += self.values[i];
        for (var i = 0; i < ii; i++)
            process(i);

      }

      self.sector = function(cx, cy, r, startAngle, endAngle, params)
      {
        var rad = Math.PI / 180;
        var x1 = cx + r * Math.cos(-startAngle * rad);
        var x2 = cx + r * Math.cos(-endAngle * rad);
        var y1 = cy + r * Math.sin(-startAngle * rad);
        var y2 = cy + r * Math.sin(-endAngle * rad);
        return self.paper.path(["M", cx, cy, "L", x1, y1, "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2, "z"]).attr(params);
      }

    },

    /* custom1 - line graph!*/
    test_old_0: function()
    {
      var self = this;

      self.requirePaper = true;

      self.init = function()
      {}

      self.setValue = function(values)
      {
         self.values = values;
      }

      self.getAnchors = function(p1x, p1y, p2x, p2y, p3x, p3y)
      {
        var l1 = (p2x - p1x) / 2,
            l2 = (p3x - p2x) / 2,
            a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
            b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));
        a = p1y < p2y ? Math.PI - a : a;
        b = p3y < p2y ? Math.PI - b : b;
        var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,
            dx1 = l1 * Math.sin(alpha + a),
            dy1 = l1 * Math.cos(alpha + a),
            dx2 = l2 * Math.sin(alpha + b),
            dy2 = l2 * Math.cos(alpha + b);
        return {
            x1: p2x - dx1,
            y1: p2y + dy1,
            x2: p2x + dx2,
            y2: p2y + dy2
        };
      }

      self.render = function()
      {
        self.paper.clear();
        if (self.values.length==0)
        return;
       // Draw
        var width = self.width,
            height = self.height,
            leftgutter = 0,
            bottomgutter = 30,
            topgutter = 20,
            colorhue = .6 || Math.random(),
            color = "hsb(" + [colorhue, .5, 1] + ")",
            r = self.paper,
            txt = {font: '12px Helvetica, Arial', fill: "#fff"},
            txt1 = {font: '10px Helvetica, Arial', fill: "#fff"},
            txt2 = {font: '12px Helvetica, Arial', fill: "#000"},
            X = (width - leftgutter) / self.values.length,
            max = Math.max.apply(Math, self.values),
            Y = (height - bottomgutter - topgutter) / max;
        r.drawGrid(leftgutter + X * .5 + .5, topgutter + .5, width - leftgutter - X, height - topgutter - bottomgutter, 10, 10, "#eee");
        var path = r.path().attr({stroke: color, "stroke-width": 4, "stroke-linejoin": "round"}),
            bgp = r.path().attr({stroke: "none", opacity: .3, fill: color}),
            label = r.set(),
            is_label_visible = false,
            leave_timer,
            blanket = r.set();
        label.push(r.text(60, 12, "24 hits").attr(txt));
        label.push(r.text(60, 27, "22 September 2008").attr(txt1).attr({fill: color}));
        label.hide();
        var frame = r.popup(100, 100, label, "right").attr({fill: "#000", stroke: "#666", "stroke-width": 2, "fill-opacity": .7}).hide();

        var p, bgpp;
        for (var i = 0, ii = self.values.length; i < ii; i++) {
            var y = Math.round(height - bottomgutter - Y * self.values[i]),
                x = Math.round(leftgutter + X * (i + .5)),
                t = r.text(x, height - 6, self.values[i]).attr(txt).toBack();
            if (!i) {
                p = ["M", x, y, "C", x, y];
                bgpp = ["M", leftgutter + X * .5, height - bottomgutter, "L", x, y, "C", x, y];
            }
            if (i && i < ii - 1) {
                var Y0 = Math.round(height - bottomgutter - Y * self.values[i - 1]),
                    X0 = Math.round(leftgutter + X * (i - .5)),
                    Y2 = Math.round(height - bottomgutter - Y * self.values[i + 1]),
                    X2 = Math.round(leftgutter + X * (i + 1.5));
                var a = self.getAnchors(X0, Y0, x, y, X2, Y2);
                p = p.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
                bgpp = bgpp.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
            }
            var dot = r.circle(x, y, 4).attr({fill: "#000", stroke: color, "stroke-width": 2});
            blanket.push(r.rect(leftgutter + X * i, 0, X, height - bottomgutter).attr({stroke: "none", fill: "#fff", opacity: 0}));
            var rect = blanket[blanket.length - 1];
            (function (x, y, data, dot) {
                var timer, i = 0;
                rect.hover(function () {
                    clearTimeout(leave_timer);
                    var side = "right";
                    if (x + frame.getBBox().width > width) {
                        side = "left";
                    }
                    var ppp = r.popup(x, y, label, side, 1);
                    frame.show().stop().animate({path: ppp.path}, 200 * is_label_visible);
                    label[0].attr({text: data + " hit" + (data == 1 ? "" : "s")}).show().stop().animateWith(frame, {translation: [ppp.dx, ppp.dy]}, 200 * is_label_visible);
                    label[1].attr({text: 'lbl ' + " September 2008"}).show().stop().animateWith(frame, {translation: [ppp.dx, ppp.dy]}, 200 * is_label_visible);
                    dot.attr("r", 6);
                    is_label_visible = true;
                }, function () {
                    dot.attr("r", 4);
                    leave_timer = setTimeout(function () {
                        frame.hide();
                        label[0].hide();
                        label[1].hide();
                        is_label_visible = false;
                    }, 1);
                });
            })(x, y, self.values[i], dot);
        }
        p = p.concat([x, y, x, y]);
        bgpp = bgpp.concat([x, y, x, y, "L", x, height - bottomgutter, "z"]);
        path.attr({path: p});
        bgp.attr({path: bgpp});
        frame.toFront();
        label[0].toFront();
        label[1].toFront();
        blanket.toFront();
      }
    }



  },
  
  
  
  
  
  
  












/////utils
(function () {

var tokenRegex = /\{([^\}]+)\}/g,
  objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties
  replacer = function (all, key, obj) {
      var res = obj;
      key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
          name = name || quotedName;
          if (res) {
              if (name in res) {
                  res = res[name];
              }
              typeof res == "function" && isFunc && (res = res());
          }
      });
      res = (res == null || res == obj ? all : res) + "";
      return res;
  },
  fill = function (str, obj) {
      return String(str).replace(tokenRegex, function (all, key) {
          return replacer(all, key, obj);
      });
  };


  Raphael.fn.popup = function (X, Y, set, pos, ret)
  {
      pos = String(pos || "top-middle").split("-");
      pos[1] = pos[1] || "middle";
      var r = 5,
          bb = set.getBBox(),
          w = Math.round(bb.width),
          h = Math.round(bb.height),
          x = Math.round(bb.x) - r,
          y = Math.round(bb.y) - r,
          gap = Math.min(h / 2, w / 2, 10),
          shapes = {
              top: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
              bottom: "M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
              right: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z",
              left: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z"
          },
          offset = {
              hx0: X - (x + r + w - gap * 2),
              hx1: X - (x + r + w / 2 - gap),
              hx2: X - (x + r + gap),
              vhy: Y - (y + r + h + r + gap),
              "^hy": Y - (y - gap)

          },
          mask = [{
              x: x + r,
              y: y,
              w: w,
              w4: w / 4,
              h4: h / 4,
              right: 0,
              left: w - gap * 2,
              bottom: 0,
              top: h - gap * 2,
              r: r,
              h: h,
              gap: gap
          }, {
              x: x + r,
              y: y,
              w: w,
              w4: w / 4,
              h4: h / 4,
              left: w / 2 - gap,
              right: w / 2 - gap,
              top: h / 2 - gap,
              bottom: h / 2 - gap,
              r: r,
              h: h,
              gap: gap
          }, {
              x: x + r,
              y: y,
              w: w,
              w4: w / 4,
              h4: h / 4,
              left: 0,
              right: w - gap * 2,
              top: 0,
              bottom: h - gap * 2,
              r: r,
              h: h,
              gap: gap
          }][pos[1] == "middle" ? 1 : (pos[1] == "top" || pos[1] == "left") * 2];
          var dx = 0,
              dy = 0,
              out = this.path(fill(shapes[pos[0]], mask)).insertBefore(set);
          switch (pos[0]) {
              case "top":
                  dx = X - (x + r + mask.left + gap);
                  dy = Y - (y + r + h + r + gap);
              break;
              case "bottom":
                  dx = X - (x + r + mask.left + gap);
                  dy = Y - (y - gap);
              break;
              case "left":
                  dx = X - (x + r + w + r + gap);
                  dy = Y - (y + r + mask.top + gap);
              break;
              case "right":
                  dx = X - (x - gap);
                  dy = Y - (y + r + mask.top + gap);
              break;
          }
          out.translate(dx, dy);
          if (ret) {
              ret = out.attr("path");
              out.remove();
              return {
                  path: ret,
                  dx: dx,
                  dy: dy
              };
          }
          set.translate(dx, dy);
          return out;
  };

  Raphael.fn.drawGrid = function (x, y, w, h, wv, hv, color)
  {
    color = color || "#000";
    var path = ["M", Math.round(x) + .5, Math.round(y) + .5, "L", Math.round(x + w) + .5, Math.round(y) + .5, Math.round(x + w) + .5, Math.round(y + h) + .5, Math.round(x) + .5, Math.round(y + h) + .5, Math.round(x) + .5, Math.round(y) + .5],
        rowHeight = h / hv,
        columnWidth = w / wv;
    for (var i = 1; i < hv; i++) {
        path = path.concat(["M", Math.round(x) + .5, Math.round(y + i * rowHeight) + .5, "H", Math.round(x + w) + .5]);
    }
    for (i = 1; i < wv; i++) {
        path = path.concat(["M", Math.round(x + i * columnWidth) + .5, Math.round(y) + .5, "V", Math.round(y + h) + .5]);
    }
    return this.path(path.join(",")).attr({stroke: color});
  };

})();